package codegen.views;

import java.io.File;
import java.io.IOException;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.myframework.JDBCCodeGenerator;

import plugin.util.EclipseUtil;

/**
 * This sample class demonstrates how to plug-in a new workbench view. The view
 * shows data obtained from the model. The sample creates a dummy model on the
 * fly, but a real implementation would connect to the model available either in
 * this or another plug-in (e.g. the workspace). The view is connected to the
 * model using a content provider.
 * <p>
 * The view uses a label provider to define how model objects should be
 * presented in the view. Each view can present the same model objects using
 * different labels and icons, if needed. Alternatively, a single label provider
 * can be shared between views in order to ensure that objects of the same type
 * are presented in the same way everywhere.
 * <p>
 */

public class TemplateView extends ViewPart {

	/**
	 * The ID of the view as specified by the extension.
	 */
	public static final String ID = "codegen.views.TemplateView";

	private TableViewer viewer;
	private Action refreshAction;
	private Action addAction;
	private Action delAction;
	private Action renameAction;
	private Action doubleClickAction;

	/*
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */

	class TempateFile {
		String fileName;
		String filePath;

		public String getFileName() {
			return fileName;
		}

		public void setFileName(String fileName) {
			this.fileName = fileName;
		}

		public String getFilePath() {
			return filePath;
		}

		public void setFilePath(String filePath) {
			this.filePath = filePath;
		}

		public TempateFile() {
			super();
		}

		@Override
		public String toString() {
			return fileName;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result
					+ ((fileName == null) ? 0 : fileName.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			TempateFile other = (TempateFile) obj;
			if (!getOuterType().equals(other.getOuterType()))
				return false;
			if (fileName == null) {
				if (other.fileName != null)
					return false;
			} else if (!fileName.equals(other.fileName))
				return false;
			return true;
		}

		public TempateFile(File file) {
			super();
			this.fileName = file.getName();
			this.filePath = file.getAbsolutePath();
		}

		private TemplateView getOuterType() {
			return TemplateView.this;
		}
	}

	class ViewContentProvider implements IStructuredContentProvider {
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object parent) {
			File dir = new File(JDBCCodeGenerator.findTemplatePath());
			File[] files = dir.listFiles();
			TempateFile[] tempateFiles = new TempateFile[files.length];
			int i = 0;
			for (File tFile : files) {
				tempateFiles[i] = new TempateFile(tFile);
				i++;
			}
			return tempateFiles;
			// return new String[] { "One", "Two1", "Three1" };
		}
	}

	class ViewLabelProvider extends LabelProvider implements
			ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return getText(obj);
		}

		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}

		public Image getImage(Object obj) {
			return PlatformUI.getWorkbench().getSharedImages()
					.getImage(ISharedImages.IMG_OBJ_FILE);
		}
	}

	class NameSorter extends ViewerSorter {
	}

	/**
	 * The constructor.
	 */
	public TemplateView() {
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		viewer.setInput(getViewSite());

		// Create the help context id for the viewer's control
		// PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),
		// "codegen.viewer");
		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				TemplateView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(refreshAction);
		manager.add(new Separator());
		manager.add(addAction);
		manager.add(renameAction);
		manager.add(delAction);
	}

	private void fillContextMenu(IMenuManager manager) {
		manager.add(refreshAction);
		manager.add(new Separator());
		manager.add(addAction);
		manager.add(renameAction);
		manager.add(delAction);
//		manager.add(renameAction);
//		manager.add(delAction);
//		// Other plug-ins can contribute there actions here
//		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(refreshAction);
		manager.add(new Separator());
		manager.add(addAction);
		manager.add(renameAction);
		manager.add(delAction);
	}

	private void makeActions() {
		refreshAction = new Action() {
			public void run() {
				// showMessage("Action 1 executed");
				viewer.refresh();
			}
		};
		refreshAction.setText("刷新视图");
		refreshAction.setToolTipText("刷新视图");
		refreshAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));// ISharedImages.IMG_ELCL_SYNCED
		//新建文件
		addAction = new Action() {
			public void run() {
				//showMessage("Action 2 executed");
				String fileName=getInputFromDialog("NEW_FILE.httl");
				if(fileName == null) return;
				File file = new File(JDBCCodeGenerator.findTemplatePath()+File.separator+fileName);
				try {
					if(file.createNewFile()){
						refreshViewer(file);
						EclipseUtil.openEditorOnFileStore(file.getAbsolutePath());
					}
				} catch (IOException e) {
					showMessage(e.getMessage());
				}
			}
		};
		addAction.setText("新建文件");
		addAction.setToolTipText("新建文件");
		addAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(ISharedImages.IMG_OBJ_ADD));

		// 文件重命名
		renameAction  = new Action() {
			public void run() {
				//showMessage("Action 2 executed");
				//getInputFromDialog();
				ISelection selection = viewer.getSelection();
				if(selection==null){
					return;
				}
				Object obj = ((IStructuredSelection) selection)
						.getFirstElement();
				TempateFile file = (TempateFile) obj;
				File oFile=new File( file.getFilePath());
				//重命名文件
				String fileName=getInputFromDialog(file.getFileName());
				if(fileName == null) return;
				File renameFile=new File( JDBCCodeGenerator.findTemplatePath()+File.separator+fileName);
				oFile.renameTo(renameFile);
				refreshViewer(renameFile);
				EclipseUtil.openEditorOnFileStore(renameFile.getAbsolutePath());
			}
		};
		renameAction.setText("重命名");
		renameAction.setToolTipText("重命名");
		renameAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(ISharedImages.IMG_ETOOL_SAVEAS_EDIT));//ISharedImages.IMG_ETOOL_SAVEAS_EDIT

		//删除文件
		delAction  = new Action() {
			public void run() {
				//showMessage("Action 2 executed");
				//getInputFromDialog();
				ISelection selection = viewer.getSelection();
				if(selection!=null){
					Object obj = ((IStructuredSelection) selection)
							.getFirstElement();
					TempateFile file = (TempateFile) obj;
					File delFile=new File( file.getFilePath());
					if(confirm("删除文件"+file.getFilePath()))
						delFile.delete();
					viewer.refresh();
				}

			}
		};
		delAction.setText("删除文件");
		delAction.setToolTipText("删除文件");
		delAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
				.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));




		//打开编辑区
		doubleClickAction = new Action() {
			public void run() {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection) selection)
						.getFirstElement();
				TempateFile file = (TempateFile) obj;
				// showMessage("Double-click detected on "+file.getFilePath());
				EclipseUtil.openEditorOnFileStore(file.getFilePath());
			}
		};
	}

	private void refreshViewer(File file ) {
		viewer.refresh();
		if(file.exists()){
			IStructuredSelection selection = new StructuredSelection(new TempateFile(file) );
			viewer.setSelection(selection);
		}
	}

	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				doubleClickAction.run();
			}
		});
	}

	private void showMessage(String message) {
		MessageDialog.openInformation(viewer.getControl().getShell(),
				"CODEGEN", message);
	}

	private boolean confirm(String message) {
		return MessageDialog.openConfirm(viewer.getControl().getShell(),
				"CODEGEN", message);
	}

	private String getInputFromDialog(String defFileName) {
		InputDialog input = new InputDialog(viewer.getControl().getShell(),
				"输入文件名", "请输入文件名:",
				defFileName, null);
		input.create();
		if (input.open() == Window.OK) {
			System.out.println(input.getValue());
			return input.getValue();
		}
		return null ;
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}